# 一共有7个代码文件，每个文件对应一个最能体现的原则，请找出每个原则对应的代码文件，然后分析该代码文件是如何体现该原则的。

# 请将文件名修改为相应的原则名称，如：1.单一职责原则.py。并回答以下问题。然后将代码文件上传到之前实验创建的码云仓库中。
# 将码云代码仓库里新建文件夹code_snippets，将代码文件放入该文件夹中。

# 1.运行代码
# 输出如下：
# 普通用户 101 借阅了图书 B1001，最长借阅时间为 14 天。
# VIP用户 201 借阅了图书 B2002，最长借阅时间为 30 天。

# 2. 指出该代码体现了哪个原则
# 体现了策略模式原则

# 3. 请说明该代码是如何体现该原则
# 策略模式是一种行为设计模式，它定义了一系列算法，并将每一个算法封装起来，使它们可以互换。策略模式让算法的变化独立于使用算法的客户。
#
# 在这个例子中：
#
# 抽象策略类（BorrowStrategy）：定义了一个公共接口，用于封装不同的借书策略。这个接口有一个抽象方法borrow，所有具体的策略类都必须实现这个方法。
# 具体策略类（RegularUserBorrowStrategy和VIPUserBorrowStrategy）：这些类实现了BorrowStrategy接口，提供了具体的借书策略。每个策略类都实现了borrow方法，但具体行为（如借阅时间）是不同的。
# 上下文类（LibraryManagementSystem）：这个类使用了策略模式的客户端代码。它持有一个BorrowStrategy的引用，并调用其borrow方法来执行具体的借书策略。上下文类不知道它持有的是哪一个具体的策略对象，它只知道它持有的是一个BorrowStrategy对象。
# 通过策略模式，我们可以在不修改上下文类（LibraryManagementSystem）的情况下添加新的借书策略。我们只需要创建一个新的策略类，实现BorrowStrategy接口，并将其传递给上下文类即可。这样，上下文类就可以与不同的策略对象进行交互，而无需知道它们的具体实现细节。
#
# 此外，策略模式还提高了代码的可维护性和可扩展性。如果我们需要修改某个具体的策略，我们只需要修改那个策略类，而不会影响其他部分的代码。同样，如果我们需要添加新的策略，我们只需要创建新的策略类，并将其添加到系统中即可。


from abc import ABC, abstractmethod

# 抽象的借书策略类
class BorrowStrategy(ABC):
    @abstractmethod
    def borrow(self, user_id, book_id):
        pass

# 普通用户的借书策略
class RegularUserBorrowStrategy(BorrowStrategy):
    def borrow(self, user_id, book_id):
        print(f"普通用户 {user_id} 借阅了图书 {book_id}，最长借阅时间为 14 天。")

# VIP用户的借书策略
class VIPUserBorrowStrategy(BorrowStrategy):
    def borrow(self, user_id, book_id):
        print(f"VIP用户 {user_id} 借阅了图书 {book_id}，最长借阅时间为 30 天。")

# 借书功能类，它依赖于抽象的策略类
class LibraryManagementSystem:
    def __init__(self, borrow_strategy: BorrowStrategy):
        self.borrow_strategy = borrow_strategy

    def borrow_book(self, user_id, book_id):
        self.borrow_strategy.borrow(user_id, book_id)

# 测试示例
if __name__ == "__main__":
    # 普通用户借书
    regular_borrow_strategy = RegularUserBorrowStrategy()
    library_system = LibraryManagementSystem(regular_borrow_strategy)
    library_system.borrow_book(user_id=101, book_id="B1001")

    # VIP用户借书
    vip_borrow_strategy = VIPUserBorrowStrategy()
    library_system = LibraryManagementSystem(vip_borrow_strategy)
    library_system.borrow_book(user_id=201, book_id="B2002")
